package net.chenlin.dp.modules.newBusiness.service.impl;

import lombok.extern.slf4j.Slf4j;
import net.chenlin.dp.common.entity.R;
import net.chenlin.dp.common.utils.CommonUtils;
import net.chenlin.dp.modules.newBusiness.dao.DeviceCountMapper;
import net.chenlin.dp.modules.newBusiness.dao.NewDistrictManageMapper;
import net.chenlin.dp.modules.newBusiness.entity.dto.DayCountDto;
import net.chenlin.dp.modules.newBusiness.entity.dto.TrendChartDto;
import net.chenlin.dp.modules.newBusiness.entity.vo.DeviceCountVo;
import net.chenlin.dp.modules.newBusiness.entity.vo.NewDistrictVo;
import net.chenlin.dp.modules.newBusiness.entity.vo.TopologyNodeTreeVo;
import net.chenlin.dp.modules.newBusiness.entity.vo.TrendChartVo;
import net.chenlin.dp.modules.newBusiness.service.DeviceCountService;
import net.chenlin.dp.modules.utils.TreeUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: Yansgm
 * @Description:
 * @Date: 2025-04-27 15:39:23
 */
@Service
@Slf4j
public class DeviceCountServiceImpl implements DeviceCountService {

    @Autowired
    private DeviceCountMapper mapper;

    @Autowired
    private NewDistrictManageMapper districtManageMapper;

    @Override
    public R getdayCount(DayCountDto dto) {

        NewDistrictVo vo = districtManageMapper.getDistrictInfo(dto.getDistrictId());
        // 获取台区下面的所有的设备ID
        List<DeviceCountVo> list = mapper.getAllDeviceId(dto.getDistrictId());
        List<TopologyNodeTreeVo> nodeList = districtManageMapper.getTopologyNodeId(dto.getDistrictId(),3);
        TopologyNodeTreeVo newTreeVo = new TopologyNodeTreeVo();
        for (DeviceCountVo deviceCountVo : list){
            String deviceNum = deviceCountVo.getNodeName();
            // 获取当前设备下面的所有节点
            newTreeVo = mapper.getTopologyNodeTreeVo(deviceNum);
            if(CollectionUtils.isNotEmpty(nodeList)){
                addSubCompany(newTreeVo, nodeList);
            }

            List<TopologyNodeTreeVo> childIds = TreeUtils.getChildIds(newTreeVo);

            // 计算监测设备的关联用户数 = 该设备自身直接关联的用户数+该设备下级设备关联的用户数（如果有多级关系，则逐级递归计算直至末级）

            List<TopologyNodeTreeVo> deviceList = childIds.stream().filter(treeVo -> treeVo.getNodeType() == 3).collect(Collectors.toList());
            Integer usersNum = deviceList.stream().mapToInt(TopologyNodeTreeVo::getUserNum).sum();
            deviceCountVo.setUsersNum(usersNum);

            BigDecimal usersCount = new BigDecimal(0.00);
            // 计算每台监测设备关联的户表计量总和 = 该设备自身关联的所有户表的电量总和 + 该设备下级设备关联的户表电量总和（如果有多级关系，则逐级递归计算直至末级）
            for (TopologyNodeTreeVo treeVo : deviceList){
                BigDecimal usersCount1 = mapper.getUsersCount(treeVo.getDeviceAlias(), dto.getTime(), dto.getDistrictId());
                if(usersCount1 == null){
                    usersCount = usersCount.add(new BigDecimal(0.00));
                }else {
                    usersCount = usersCount.add(usersCount1);
                }
            }
            deviceCountVo.setUsersCount(usersCount);

            // 计算 - 监测设备计量结果

            BigDecimal deviceDayCount = new BigDecimal(0.00);
            BigDecimal querydeviceDayCount = mapper.getDeviceDayCount(deviceNum,dto.getTime());
            if(querydeviceDayCount != null ){
                deviceDayCount = querydeviceDayCount;
            }
            deviceCountVo.setDeviceCount(deviceDayCount);
            // 计算电量损失以及线损率
            if(deviceDayCount.compareTo(usersCount) > 0){
                deviceCountVo.setLoss(deviceDayCount.subtract(usersCount));

                BigDecimal result = deviceCountVo.getLoss().divide(deviceDayCount, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                String lineLossQualifiedTarget = vo.getLineLossQualifiedTarget();
                BigDecimal bigDecimal = new BigDecimal(lineLossQualifiedTarget);
                if(bigDecimal.compareTo(result) == 1 || bigDecimal.compareTo(result) == 0 ){
                    deviceCountVo.setIsAbnormal(Boolean.FALSE);
                }else{
                    deviceCountVo.setIsAbnormal(Boolean.TRUE);
                }
                deviceCountVo.setLineLossRate(result.toString()+"%");

            }
        }
        return CommonUtils.msg(list);
    }

    @Override
    public R getTrendChart(TrendChartDto dto) {

        // 获取当前设备所属台区
        Integer districtId = mapper.getDistrictId(dto.getDeviceNo());
        dto.setDistrictId(districtId);

        //获取 - 监测设备计量结果
        List<TrendChartVo> list = mapper.getDeviceCountByType(dto);

        List<TopologyNodeTreeVo> nodeList = districtManageMapper.getTopologyNodeId(districtId,3);

        TopologyNodeTreeVo newTreeVo = new TopologyNodeTreeVo();
        // 获取当前设备下面的所有节点
        newTreeVo = mapper.getTopologyNodeTreeVo(dto.getDeviceNo());
        if(CollectionUtils.isNotEmpty(nodeList)){
            addSubCompany(newTreeVo, nodeList);
        }

        List<TopologyNodeTreeVo> childIds = TreeUtils.getChildIds(newTreeVo);
        List<TopologyNodeTreeVo> deviceList = childIds.stream().filter(treeVo -> treeVo.getNodeType() == 3).collect(Collectors.toList());


        list.stream().forEach(trendChartVo -> {
            // 计算 - 户表计量结果
            BigDecimal usersCount = new BigDecimal(0.00);
            // 计算每台监测设备关联的户表计量总和 = 该设备自身关联的所有户表的电量总和 + 该设备下级设备关联的户表电量总和（如果有多级关系，则逐级递归计算直至末级）
            for (TopologyNodeTreeVo treeVo : deviceList){
                BigDecimal usersCount1 = mapper.getUsersCount(treeVo.getDeviceAlias(), trendChartVo.getDatetime(), dto.getDistrictId());
                if(usersCount1 == null){
                    usersCount = usersCount.add(new BigDecimal(0.00));
                }else {
                    usersCount = usersCount.add(usersCount1);
                }
            }
            trendChartVo.setUsersCount(usersCount);

            // 计算电量损失以及线损率
            if(trendChartVo.getDeviceCount().compareTo(usersCount) > 0){
                trendChartVo.setLoss(trendChartVo.getDeviceCount().subtract(usersCount));

                BigDecimal result = trendChartVo.getLoss().divide(trendChartVo.getDeviceCount(), 2, RoundingMode.HALF_UP);
                trendChartVo.setLineLossRate(result.multiply(new BigDecimal(100)));
            }
        });
        return CommonUtils.msg(list);
    }

    public static TopologyNodeTreeVo addSubCompany(TopologyNodeTreeVo company, List<TopologyNodeTreeVo> data) {
        //构造一个子公司列表
        List<TopologyNodeTreeVo> subCompany = new ArrayList<>();
        for (TopologyNodeTreeVo item : data) {//遍历数据
            //如果遍历到的部门是当前部门的子部门
            if (item.getParentNodeId().equals(company.getNodeId())) {
                //把遍历到的公司添加到子公司列表，并且递归地调用本方法
                TopologyNodeTreeVo topologyNodeTreeVo = addSubCompany(item, data);
                subCompany.add(topologyNodeTreeVo);
            }
        }
        company.setChild(subCompany);
        return company;
    }
}
